<?php
	
	namespace Aspic;
	use Aspic as A;
	
	/**
	* Provide possibilities to manage a multilanguage website
	*/
	class LanguageManager {
		
		const STORAGE_TYPE_FUNC_PREFIX = 'getLanguageData_';
		
		const STORAGE_TYPE_INI = 'ini';
		const STORAGE_TYPE_ARRAY = 'array';
		const STORAGE_TYPE_JSON = 'json';
		
		/**
		* @var array Language strings
		*/
		protected $_data;
		
		protected $_prefix;
		
		/**
		* @param string $_lngInfoStorageType Storage type
		*/
		public function __construct($storageType = null) {
			if(is_null($storageType)) {
				$storageType = self::STORAGE_TYPE_INI;
			}
		
			$this->_lngStorageType = $storageType;
			
			$this->_data = array();
			$this->_prefix = '';
		}
		
		/**
		* Define current language used in the script
		* 
		* @param string $filePath Path to the language file
		* @param bool $mergeCurrent Set if the new language will merge (true) or replace the current language
		* 
		* @return bool True if language file exists and false if it doesn't
		*/
		public function loadFromFile($filePath, $mergeCurrent = false) {
			// var_dump(($this->_data));
			if(is_file($filePath)) {
				$cts = file_get_contents($filePath);
				// var_dump($cts);
				return $this->loadFromData($cts, $mergeCurrent);
			}
			else {
				return false;
			}
		}
		
		public function loadFromData($data, $mergeCurrent = false) {
			if($mergeCurrent) {
				$this->_data = array_merge($this->_data, $this->getLanguageData($data));
			}
			else {
				$this->_data = $this->getLanguageData($data);
			}
			// var_dump($this->_data);
			return true;
		}
		
		/**
		 * Allow to get the correct plural translation depending on $pluralNumber
		 * @param array $keys An array with 0 => Singular translation key, 1 => plural transaltion key
		 * @param type $pluralNumber A number that define if plural translatino is used
		 * @param mixed $args,... Optionnal params for the translation (like printf do)
		 */
		public function getPluralTrans(array $keys, $pluralNumber, $args = null) {
			$fromArgsArgs = array();
			
			if($args !== null) {
				$fromArgsArgs = array_slice(func_get_args(), 2);
			}
			
			if ($pluralNumber > 1) {
				return $this->getTranslationArray($keys[1], $fromArgsArgs);
			}
			else {
				return $this->getTranslationArray($keys[0], $fromArgsArgs);
			}
		}
		
		/**
		* Get the traduction string of a key for the current language.
		* For more efficiency, developper must create two function like __() and _e() to respectively get and write traduction
		* 
		* @param string $key Traduction key (params are given to String::fromArgs method) 
		* @param mixed $args, ... Params that will replace in the language expression (see php printf function)
		*/
		public function getTrans($key) {
			$args = array();
			
			if(func_num_args() > 1) {
				$args = array_slice(func_get_args(), 1);
			}
			
			return $this->getTranslationArray($key, $args);
		}
		
		
		public function getTranslation($key) {
			return call_user_func_array(array($this, 'getTrans'), func_get_args());
		}
		
		/**
		* Same as getTranslation but string params are passed as an array (like UString::fromArgsArray)
		*/
		public function getTranslationArray($key, array $params = array()) {
			$key = $this->_prefix.$key;
		
			if($this->_data) {
				if(isset($this->_data[$key])) {
					$trad = $this->_data[$key];
					
					if(count($params)) {
						$trad = UString::fromArgsArray($trad, $params);
					}
				
					return $trad;
				}
				else {
					return $key;
				}
			}
			else {
				return $key;
			}
		}
		
		/**
		* Add a prefix to all call of getTranslation
		* Ex: setPrefix('clients'); getTranslation('firstname') will be the same as getTranslation('clients.firstname');
		*/
		public function setPrefix($prefix) {
			$this->_prefix = $prefix;
		}
		
		public function removePrefix() {
			$this->_prefix = '';
		}
		
		/**
		* Get language data with specified storage type from file
		* @return array Language strings or empty array if problem (fileName doesn't exist, wrong storage type)
		*/
		protected function getLanguageData($data) {
			$methodName = self::STORAGE_TYPE_FUNC_PREFIX.$this->_lngStorageType;
			
			if(method_exists($this, $methodName)) {
				$_data = call_user_func(array($this, $methodName), $data);
				
				return $_data;
			}
			
			return array();
		}
		
		/**
		* Get language data from ini file
		* Each var in a section will be transformed into : sectionName.var
		*/
		protected function getLanguageData_ini($data) {
			$rawData = parse_ini_string($data, true);
			// var_dump($rawData);
			$trans = array();
			
			foreach($rawData as $sectionOrKey => $item) {
				if(is_array($item)) {
					foreach($item as $key => $sectItem) {
						$trans[$sectionOrKey.'.'.$key] = $sectItem;
					}
				}
				else {
					$trans[$sectionOrKey] = $item;
				}
			}
			
			// var_dump($data);
			return $trans;
		}
		
		/**
		* Get language data from php file returning an array
		*/
		protected function getLanguageData_array($data) {
			$lngData = $data;
			$lngData = A\UString::removeFirst($lngData, '<?php');
			$lngData = A\UString::removeLast($lngData, '?>');
			$lngData = eval($lngData);
			
			$lngData = A\UArray::multiDimToOneDim($lngData);
			// var_dump($lngData);
			
			return $lngData;
		}
		
		/**
		* Get language data from json file
		* Json data must not be surrounded with { }
		* Each var nested var will be transformed into : parent1.parent2.parentX.var
		*/
		protected function getLanguageData_json($data) {
			$json = '{'.$data.'}';
			
			$arr = json_decode($json, true);
			// var_dump($json);
			// var_dump($arr);
			$data = array();
			
			$data = A\UArray::multiDimToOneDim($arr);
			
			return $data;
		}
		
		
	}
	
	/*
	
	### EXAMPLE ###
	
	function __($key) {
		return $GLOBALS['lngManager']->getTranslation($key);
	}
	
	function _e($key) {
		print __($key);
	}
	
	$lngManager = new LanguageManager(LanguageManager::STORAGE_TYPE_INI);

	$lngManager->loadLanguageFile('lang/en.ini');
	
	_e('welcomeTitle'); // Welcome

	
	*/
?>